﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace NUnitResultsExplorer
{
    /// <summary>
    /// Represents an item that can be expanded or collapsed.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Expandable<T> : INotifyPropertyChanged
    {
        /// <summary>
        /// Gets the inner object.
        /// </summary>
        public T Object { get; private set; }

        /// <summary>
        /// Gets the sub-expandables.
        /// </summary>
        public IList<Expandable<T>> SubExpandables { get; private set; }

        /// <summary>
        /// Whether or not this item is expanded.
        /// </summary>
        private Boolean isExpanded;

        /// <summary>
        /// Gets or sets whether or not this item is expanded.
        /// </summary>
        public Boolean IsExpanded
        {
            get
            {
                return isExpanded;
            }
            set
            {
                if (isExpanded != value)
                {
                    isExpanded = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("IsExpanded"));
                }
            }
        }

        /// <summary>
        /// Creates a new Expandable.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="isExp"></param>
        /// <param name="subExpandables"></param>
        public Expandable(T obj, Boolean isExp, IList<Expandable<T>> subExpandables)
        {
            if (subExpandables == null)
            {
                throw new ArgumentNullException("subExpandables");
            }

            Object = obj;
            SubExpandables = subExpandables;
            isExpanded = isExp;
        }

        #region INotifyPropertyChanged Members

        /// <summary>
        /// Raised when a property value on this object changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        /// <summary>
        /// Raises the PropertyChanged event.
        /// </summary>
        /// <param name="e"></param>
        protected void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }

            var handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        /// <summary>
        /// Sets this instance's Expanded property, as well as all sub-Expandables.
        /// </summary>
        /// <param name="isExpanded"></param>
        public void SetExpanded(Boolean isExpanded)
        {
            IsExpanded = isExpanded;

            foreach (var subNode in SubExpandables)
            {
                subNode.SetExpanded(isExpanded);
            }
        }
    }
}
